package etcdUtils

import (
	"context"
	"encoding/json"
	"fmt"
	clientv3 "go.etcd.io/etcd/client/v3"
	"log"
)

// EtcdRegister 实现 Etcd 服务注册功能

type EtcdRegister struct {
	Client *clientv3.Client // Etcd 客户端
	Lease  clientv3.Lease   // 租约
}

// Register 注册服务
func (r *EtcdRegister) Register(ctx context.Context, serviceName string, claims ServerEntity) error {
	// 创建租约
	leaseResp, err := r.Lease.Grant(ctx, 5)
	if err != nil {
		return err
	}
	marshal, err := json.Marshal(claims)
	if err != nil {
		return err
	}
	// 注册服务
	key := fmt.Sprintf("/%s/%s", serviceName, claims)
	_, err = r.Client.Put(ctx, key, string(marshal), clientv3.WithLease(leaseResp.ID))
	if err != nil {
		return err
	}

	// 自动续租
	keepAlive, err := r.Lease.KeepAlive(ctx, leaseResp.ID)
	if err != nil {
		return err
	}
	go r.watch(ctx, keepAlive)
	// 监听租约状态

	return nil
}

func (r *EtcdRegister) watch(ctx context.Context, keepAlive <-chan *clientv3.LeaseKeepAliveResponse) {
	for {
		select {
		case <-ctx.Done():
			return
		case ka, ok := <-keepAlive:
			if !ok {
				log.Println("租约已失效")
				return
			}
			log.Printf("续租成功:%v TTL=%d", ka.ID, ka.TTL)
		}
	}
}

func (r *EtcdRegister) Close() {
	r.Client.Close()
}
func NewRg(endpoints ...string) (register *EtcdRegister) {
	client, err := clientv3.New(clientv3.Config{
		Endpoints: endpoints, // Etcd 服务器地址
	})
	if err != nil {
		log.Fatal(err)
	}
	//defer test.Close()

	// 创建租约
	lease := clientv3.NewLease(client)

	// 创建服务注册器
	register = &EtcdRegister{
		Client: client,
		Lease:  lease,
	}
	return

}
